﻿#define debug

using Newtonsoft.Json;
using RXY_Mall.Core;
using RXY_Mall.Core.Tool;
using RXY_Mall.Services;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Http.Filters;

namespace RXY_Mall.AdminApi.Common
{
    public class ApiSecurityFilter : ActionFilterAttribute
    {
        public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            ResponseService<string> result = new ResponseService<string>();
            result.code = 3;

            try
            {
                var request = actionContext.Request;
                string method = request.Method.Method;
                string manager_id = String.Empty, timestamp = string.Empty, nonce = string.Empty, signature = string.Empty, version = string.Empty;
                int managerid = 0;

                //用户ID
                if (request.Headers.Contains("manager_id"))
                {
                    manager_id = HttpUtility.UrlDecode(request.Headers.GetValues("manager_id").FirstOrDefault());
                }
                //时间戳
                if (request.Headers.Contains("timestamp"))
                {
                    timestamp = HttpUtility.UrlDecode(request.Headers.GetValues("timestamp").FirstOrDefault());
                }
                //随机数
                if (request.Headers.Contains("nonce"))
                {
                    nonce = HttpUtility.UrlDecode(request.Headers.GetValues("nonce").FirstOrDefault());
                }
                //签名
                if (request.Headers.Contains("signature"))
                {
                    signature = HttpUtility.UrlDecode(request.Headers.GetValues("signature").FirstOrDefault());
                }
                //版本号V1.0.0
                if (request.Headers.Contains("version"))
                {
                    version = HttpUtility.UrlDecode(request.Headers.GetValues("version").FirstOrDefault());
                    if (version == "5b666b50-7acb-4fe1-8a04-aeb12779d6f8")
                    {
                        base.OnActionExecuting(actionContext);
                        return;
                    }
                }
                //string ip = DcRequest.GetIP();
                //LogHelper.WriteLog(string.Format("IP:{0}", ip));

                bool isDebug = false;
#if DEBUG
                isDebug = true;
                LogHelper.WriteLog("进入调试");
#endif
                if (isDebug)
                {
                    return;
                }

                string actionName = actionContext.ActionDescriptor.ActionName;

                LogHelper.WriteLog(string.Format("method:{0},manager_id:{1},timestamp:{2},nonce:{3},signature:{4},version:{5},actionName:{6}", method, manager_id, timestamp, nonce, signature, version, actionName));
                //判断关闭的功能
                if (AppConfig.AppCloseFunction.Contains(actionName))
                {
                    result.code = 0;
                    result.msg = AppConfig.FunctionCloseMessage;
                    actionContext.Response = HttpResponseExtension.toJson(JsonConvert.SerializeObject(result));
                    base.OnActionExecuting(actionContext);
                    return;
                }

                //过滤功能
                if (AppConfig.AppFilterFunction.Contains(actionName))
                {
                    base.OnActionExecuting(actionContext);
                    return;
                }

                //Session过滤功能
                if (version.Equals("wap"))
                {
                    var userId = SessionHelper.Get("qujia");
                    if (userId == null)
                    {
                        result.msg = "请求参数不完整或不正确";
                        actionContext.Response = HttpResponseExtension.toJson(JsonConvert.SerializeObject(result));
                        base.OnActionExecuting(actionContext);
                        return;
                    }
                    manager_id = userId.ToString();
                }

                //判断请求头是否包含以下参数
                if (string.IsNullOrEmpty(manager_id) || (!int.TryParse(manager_id, out managerid) || string.IsNullOrEmpty(timestamp) || string.IsNullOrEmpty(nonce) || string.IsNullOrEmpty(signature)))
                {
                    result.msg = "请求参数不完整或不正确";
                    actionContext.Response = HttpResponseExtension.toJson(JsonConvert.SerializeObject(result));
                    base.OnActionExecuting(actionContext);
                    return;
                }
                //判断timespan是否有效
                double ts1 = 0;
                double ts2 = (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
                bool timespanvalidate = double.TryParse(timestamp, out ts1);
                double ts = ts2 - ts1;
                //1分钟
                bool falg = ts > 1 * 60;
                if (falg || (!timespanvalidate))
                {
                    result.msg = "URL已经失效";
                    actionContext.Response = HttpResponseExtension.toJson(JsonConvert.SerializeObject(result));
                    base.OnActionExecuting(actionContext);
                    return;
                }

                //判断token是否有效
                ManagerToken token = (ManagerToken)HttpRuntime.Cache.Get(managerid.ToString());

                string sign_token = string.Empty;
                if (HttpRuntime.Cache.Get(managerid.ToString()) == null)
                {
                    result.msg = "请求TOKEN失效";
                    actionContext.Response = HttpResponseExtension.toJson(JsonConvert.SerializeObject(result));
                    base.OnActionExecuting(actionContext);
                    return;
                }
                else
                {
                    sign_token = token.sign_token.ToString();
                }
                string data = string.Empty;
                bool flag = false;
                switch (method)
                {
                    case "POST":
                        //获取请求消息提数据
                        Stream stream = actionContext.Request.Content.ReadAsStreamAsync().Result;
                        Encoding encoding = Encoding.UTF8;
                        stream.Position = 0;
                        using (StreamReader reader = new StreamReader(stream, encoding))
                        {
                            data = reader.ReadToEnd().ToString();
                        }

                        if (string.IsNullOrWhiteSpace(data))
                        {
                            result.msg = "数据不能为空";
                            actionContext.Response = HttpResponseExtension.toJson(JsonConvert.SerializeObject(result));
                            base.OnActionExecuting(actionContext);
                            return;
                        }
                        LogHelper.WriteLog(data);


                        MangerBaseInput input = JsonConvert.DeserializeObject<MangerBaseInput>(data);
                        if (input.manager_id.ToString() == manager_id)
                        {
                            flag = true;
                        }
                        break;
                    case "GET":
                        //根据请求类型拼接参数
                        NameValueCollection form = HttpContext.Current.Request.QueryString;
                        StringBuilder query = new StringBuilder();
                        //第一步：取出所有get参数
                        //IDictionary<string, string> parameters = new Dictionary<string, string>();
                        string bodyUserId = "";
                        for (int f = 0; f < form.Count; f++)
                        {
                            string key = form.Keys[f];
                            if (key == "manager_id")
                            {
                                bodyUserId = form[key];
                            }

                            query.Append(key).Append(form[key]);
                        }

                        //// 第二步：把字典按Key的字母顺序排序
                        //IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(parameters);
                        //IEnumerator<KeyValuePair<string, string>> dem = sortedParams.GetEnumerator();

                        //// 第三步：把所有参数名和参数值串在一起
                        //StringBuilder query = new StringBuilder();                   
                        //while (dem.MoveNext())
                        //{
                        //    string key = dem.Current.Key;
                        //    string value = dem.Current.Value;
                        //    if (!string.IsNullOrEmpty(key))
                        //    {
                        //        query.Append(key).Append(value);
                        //    }
                        //}
                        data = query.ToString();
                        LogHelper.WriteLog(data);
                        if (bodyUserId == manager_id)
                        {
                            flag = true;
                        }
                        break;
                    default:
                        result.msg = "HTTP请求类型不合法";
                        actionContext.Response = HttpResponseExtension.toJson(JsonConvert.SerializeObject(result));
                        base.OnActionExecuting(actionContext);
                        return;
                }
                //判断UserId是否一致
                if (!flag)
                {
                    result.msg = "非法访问用户";
                    actionContext.Response = HttpResponseExtension.toJson(JsonConvert.SerializeObject(result));
                    base.OnActionExecuting(actionContext);
                    return;
                }
                flag = false;

                LogHelper.WriteLog(string.Format("version:{0},signature:{1}", version, signature));
                if (version == "wap")
                {
                    flag = true;
                }
                else
                {
                    flag = SignExtension.ValidateSign(timestamp, nonce, managerid, version, sign_token, data, signature);
                }
                if (!flag)
                {
                    result.msg = "账号已在其他的设备登录，请重新登录";
                    actionContext.Response = HttpResponseExtension.toJson(JsonConvert.SerializeObject(result));
                    base.OnActionExecuting(actionContext);
                    return;
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex);
                result.msg = ex.Message;
                actionContext.Response = HttpResponseExtension.toJson(JsonConvert.SerializeObject(result));
                base.OnActionExecuting(actionContext);
                return;
            }

            base.OnActionExecuting(actionContext);
        }

        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
        {
            base.OnActionExecuted(actionExecutedContext);
        }

    }
}